#### 16.19.2 Attribute Expressions

RTL expressions used to define attributes use the codes described above plus a few specific to attribute definitions, to be discussed below. Attribute value expressions must have one of the following forms:

`(const_int` i`)`
  The integer i specifies the value of a numeric attribute. i must be non-negative.

  The value of a numeric attribute can be specified either with a `const_int`, or as an integer represented as a string in `const_string`, `eq_attr` (see below), `attr`, `symbol_ref`, simple arithmetic expressions, and `set_attr` overrides on specific instructions (see Tagging Insns).

`(const_string` value`)`
  The string value specifies a constant attribute value. If value is specified as ``"*"`', it means that the default value of the attribute is to be used for the insn containing this expression. ``"*"`' obviously cannot be used in the default expression of a `define_attr`.

  If the attribute whose value is being specified is numeric, value must be a string containing a non-negative integer (normally `const_int` would be used in this case). Otherwise, it must contain one of the valid values for the attribute.

`(if_then_else` test true-value false-value`)`
  test specifies an attribute test, whose format is defined below. The value of this expression is true-value if test is true, otherwise it is false-value.

`(cond [`test1 value1`...]` default`)`
  The first operand of this expression is a vector containing an even number of expressions and consisting of pairs of test and value expressions. The value of the `cond` expression is that of the value corresponding to the first true test expression. If none of the test expressions are true, the value of the `cond` expression is that of the default expression.

test expressions can have one of the following forms:

`(const_int` i`)`
  This test is true if i is nonzero and false otherwise.

`(not` test`)`
`(ior` test1 test2`)`
`(and` test1 test2`)`
  These tests are true if the indicated logical function is true.

`(match_operand:`m n pred constraints`)`
  This test is true if operand n of the insn whose attribute value is being determined has mode m (this part of the test is ignored if m is `VOIDmode`) and the function specified by the string pred returns a nonzero value when passed operand n and mode m (this part of the test is ignored if pred is the null string).

  The constraints operand is ignored and should be the null string.

`(match_test` c-expr`)`
  The test is true if C expression c-expr is true. In non-constant attributes, c-expr has access to the following variables:
  insn
    The rtl instruction under test.
  which_alternative
    The `define_insn` alternative that insn matches. See Output Statement.
  operands
    An array of insn's rtl operands.

  c-expr behaves like the condition in a C `if` statement, so there is no need to explicitly convert the expression into a boolean 0 or 1 value. For example, the following two tests are equivalent:

                (match_test "x & 2")
                (match_test "(x & 2) != 0")

`(le` arith1 arith2`)`
`(leu` arith1 arith2`)`
`(lt` arith1 arith2`)`
`(ltu` arith1 arith2`)`
`(gt` arith1 arith2`)`
`(gtu` arith1 arith2`)`
`(ge` arith1 arith2`)`
`(geu` arith1 arith2`)`
`(ne` arith1 arith2`)`
`(eq` arith1 arith2`)`
  These tests are true if the indicated comparison of the two arithmetic expressions is true. Arithmetic expressions are formed with `plus`, `minus`, `mult`, `div`, `mod`, `abs`, `neg`, `and`, `ior`, `xor`, `not`, `ashift`, `lshiftrt`, and `ashiftrt` expressions.

  `const_int` and `symbol_ref` are always valid terms (see Insn Lengths,for additional forms). `symbol_ref` is a string denoting a C expression that yields an `int` when evaluated by the ``get_attr_...`' routine. It should normally be a global variable.

`(eq_attr` name value`)`
  name is a string specifying the name of an attribute.

  value is a string that is either a valid value for attribute name, a comma-separated list of values, or ``!`' followed by a value or list. If value does not begin with a ``!`', this test is true if the value of the name attribute of the current insn is in the list specified by value. If value begins with a ``!`', this test is true if the attribute's value is not in the specified list.

  For example,

                (eq_attr "type" "load,store")

  is equivalent to

                (ior (eq_attr "type" "load") (eq_attr "type" "store"))

  If name specifies an attribute of ``alternative`', it refers to the value of the compiler variable `which_alternative` (see Output Statement) and the values must be small integers. For example,

                (eq_attr "alternative" "2,3")

  is equivalent to

                (ior (eq (symbol_ref "which_alternative") (const_int 2))
                     (eq (symbol_ref "which_alternative") (const_int 3)))

  Note that, for most attributes, an `eq_attr` test is simplified in cases where the value of the attribute being tested is known for all insns matching a particular pattern. This is by far the most common case.

`(attr_flag` name`)`
  The value of an `attr_flag` expression is true if the flag specified by name is true for the `insn` currently being scheduled.

  name is a string specifying one of a fixed set of flags to test. Test the flags `forward` and `backward` to determine the direction of a conditional branch.

  This example describes a conditional branch delay slot which can be nullified for forward branches that are taken (annul-true) or for backward branches which are not taken (annul-false).

                (define_delay (eq_attr "type" "cbranch")
                  [(eq_attr "in_branch_delay" "true")
                   (and (eq_attr "in_branch_delay" "true")
                        (attr_flag "forward"))
                   (and (eq_attr "in_branch_delay" "true")
                        (attr_flag "backward"))])

  The `forward` and `backward` flags are false if the current `insn` being scheduled is not a conditional branch.

  `attr_flag` is only used during delay slot scheduling and has no meaning to other passes of the compiler.

`(attr` name`)`
  The value of another attribute is returned. This is most useful for numeric attributes, as `eq_attr` and `attr_flag` produce more efficient code for non-numeric attributes.